package com.ruoyi.controller.business;


import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.domain.ProcessModel;
import com.ruoyi.service.ProcessModelService;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 流程模型Controller
 * 
 * @author ruoyi
 * @date 2021-04-29
 */
@Controller
@RequestMapping("/process/model")
public class ProcessModelController extends BaseController {
    private String prefix = "model";
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private ProcessModelService processModelService;
    @Autowired
    private ISysPostService postService;
    @Autowired
    private ISysUserService userService;

    /**
     * 进入流程模型首页
     * @return
     */
    @RequiresPermissions("process:model:view")
    @GetMapping()
    public String model() {
        return prefix + "/model";
    }

    /**
     * 查询流程模型列表
     */
    @RequiresPermissions("process:model:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(ProcessModel actReModel) {
        startPage();
        List<ProcessModel> list = processModelService.selectActReModelList(actReModel);
        return getDataTable(list);
    }

    /**
     * 新增流程模型
     */
    @GetMapping("/add")
    public String add() {
        return prefix+"/add";
    }

    /**
     * 新增保存流程模型
     */
    @RequiresPermissions("process:model:add")
    @Log(title = "流程模型", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(ProcessModel actReModel) {
        int saveFlag = 0;
        try {
            //初始化一个空模型
            Model model = repositoryService.newModel();
            //设置一些默认信息，可以用参数接收
            Long revision = actReModel.getVersion();
            String key = actReModel.getKey();
            String name = actReModel.getName();
            //用来存放流程模型描述
            String description = actReModel.getMetaInfo();
            //ModelEditorSource

            ObjectMapper objectMapper = new ObjectMapper();
            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
            editorNode.set("stencilset", stencilSetNode);
            ObjectNode modelNode = objectMapper.createObjectNode();
            modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
            modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
            modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);
            model.setName(name);
            model.setKey(key);
            model.setMetaInfo(modelNode.toString());
            model.setCategory(actReModel.getCategory());
            repositoryService.saveModel(model);
            String id = model.getId();
            repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
            saveFlag = 1 ;
        }catch(Exception e){
            saveFlag = 0;
            logger.error("流程模型保存失败！");
        }
        return toAjax(saveFlag);
    }

    /**
     * 修改流程模型
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") String id, ModelMap mmap) {
        ProcessModel actReModel = processModelService.selectActReModelById(id);
        String metaInfo = actReModel.getMetaInfo();
        HashMap<String,String> hashMap = JSON.parseObject(metaInfo, HashMap.class);
        String description = hashMap.get("description");
        actReModel.setMetaInfo(description);
        mmap.put("actReModel", actReModel);
        return prefix + "/edit";
    }

    /**
     * 修改保存流程模型
     */
    @RequiresPermissions("process:model:edit")
    @Log(title = "流程模型", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(ProcessModel actReModel) {
        HashMap<String,String> map = new HashMap<String,String>();
        map.put("name",actReModel.getName());
        map.put("description",actReModel.getMetaInfo());
        map.put("revision",actReModel.getMetaInfo());

        actReModel.setMetaInfo(JSON.toJSONString(map));
        return toAjax(
                processModelService.updateActReModel(actReModel));
    }

    /**
     * 删除流程模型
     */
    @RequiresPermissions("process:model:remove")
    @Log(title = "删除流程模型", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids) {
        return toAjax(processModelService.deleteActReModelByIds(ids));
    }

    /**
     * 导出流程模型列表
     */
    @RequiresPermissions("process:model:export")
    @Log(title = "流程模型", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(ProcessModel actReModel) {
        List<ProcessModel> list = processModelService.selectActReModelList(actReModel);
        ExcelUtil<ProcessModel> util = new ExcelUtil<ProcessModel>(ProcessModel.class);
        return util.exportExcel(list, "流程模型数据");
    }

    /**
     * 设计流程模型
     */
    @GetMapping("/design")
    public String design()  {
        return "static/modeler";
    }

    /**
     * 布署【流程模型发布】
     */
    @Log(title = "流程模型部署", businessType = BusinessType.DELETE)
    @PostMapping( "/deploye")
    @ResponseBody
    public AjaxResult deploye(String modelIds) {
        return AjaxResult.success(processModelService.deploye(modelIds));
    }

    /**
     * 流程步骤选择人
     * */
    @GetMapping("/selectHandler/{userIds}/{roleIds}/{postIds}")
    public String selectHandler(@PathVariable("userIds") String userIds, @PathVariable("roleIds") String roleIds, @PathVariable("postIds") String postIds, ModelMap mmap){
        List<SysRole> roles  = roleService.selectRoleAll();
        List<SysUser> users = userService.selectUserList(new SysUser());
        for (SysUser user : users)
        {
            if(Arrays.asList(userIds.split(",")).contains(user.getUserId()+"")){
//                user.setFlag(true);
            }
        }
        for (SysRole role : roles)
        {
            if(Arrays.asList(roleIds.split(",")).contains(role.getRoleId()+"")){
                role.setFlag(true);
            }
        }

        List<SysPost> posts = postService.selectPostAll();
        for (SysPost post : posts)
        {

            if (Arrays.asList(postIds.split(",")).contains(post.getPostId()+""))
            {
                post.setFlag(true);
            }

        }
        mmap.put("users", users);
        mmap.put("roles", roles);
        mmap.put("posts", posts);
        return prefix + "/selectHandler";
    }
    /**
     * 删除【删除流程部署】
     */
    @RequiresPermissions("process:model:delDeployed")
    @Log(title = "删除流程部署", businessType = BusinessType.DELETE)
    @PostMapping( "/delDeployed")
    @ResponseBody
    public AjaxResult delDeployed(String modelIds) {
        return toAjax(processModelService.delDeployed(modelIds));
    }
    /**
     * 流程条件选择
     */
    @GetMapping("/selectCondition/{condition}")
    public String selectCondition(@PathVariable("condition") String condition, ModelMap mmap){
        // ProcessModel actReModel = processModelService.selectActReModelById(id);
        //startPage();
        logger.info("入参condition{}",condition);
        mmap.put("condition",condition);


        return prefix + "/selectCondition";
    }
}
